當我們想要在TextView上顯示省略號 會使用屬性 android:ellipsize,
同時也要設置android:singleline = "true"
省略號才會生效
如果我想要顯示多行,又想要省略號時
只能透過自寫一個函式設定行數,以及顯示的省略文字。
/**
* mtextView : 要顯示的Textview
* mMaxLine : 要限制的行數
* mShowString : 要顯示的內容
**/
fun limitTextviewMaxLine(mtextView : TextView, mMaxLine : Int, mShowString : String){
var mViewTreeObserver= mtextView.viewTreeObserver
var mGlobalLayoutListener= object : ViewTreeObserver.OnGlobalLayoutListener{
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onGlobalLayout() {
mtextView.setText(mShowString)
when{
mtextView.lineCount > mMaxLine ->{
mtextView.viewTreeObserver.removeOnGlobalLayoutListener(this)
var endPosition=mtextView.layout.getLineEnd(mMaxLine-1)
var limitText=mShowString.subSequence(0,endPosition-3).toString()+"..."
mtextView.setText(limitText)
}
else ->{
mtextView.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
}
}
mViewTreeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener)
}
以下來解釋程式碼
var mViewTreeObserver= mtextView.viewTreeObserver
我們先宣告一個ViewTreeObserver當作觀察者,當這個元件的佈局改變跟繪製事件觸發時,
都可以藉由這個觀察者進行監聽處理。
var mGlobalLayoutListener= object : ViewTreeObserver.OnGlobalLayoutListener
之後我們在這裡使用ViewTreeObserver.OnGlobalLayoutListener來監聽布局事件,
當一個元件的layout的要求生效時,會觸發onGlobalLayout事件。
mtextView.setText(mShowString)
為什麼要寫這一行?
我們的要求是限制行數,並用省略字串代替。
所以先把要顯示的內容傳給TextView,讓接下來的判斷可以去就實際的TextView的值去操作。
為什麼不直接處理字串?
因為我們不知道這個字串在進入TextView後,會被分成幾行。
除非我們先把整個布局的寬度跟字串長度算好,然後確認會分成幾行進行處理,
不然還是交給元件去處理吧。
mtextView.lineCount > mMaxLine
這邊直接就可以由元件計算行數,是不是很方便?
這邊分為兩個部分判斷
大於mMaxLine跟小於等於mMaxLine
當大於mMaxLine時
var endPosition=mtextView.layout.getLineEnd(mMaxLine-1)
var limitText=mShowString.subSequence(0,endPosition-3).toString()+"..."
取得最大行數該行的最後一個字元位置後,往前移3個字元並截取內容,後面加上"..."取代後面的內容。
mtextView.viewTreeObserver.removeOnGlobalLayoutListener(this)
記得每次判斷後移除OnGlobalLayoutListener,不然影響效能
我們在使用函式時,使用limitTextviewMaxLine(要使用此格式的TextView,要限制的行數,輸入內容)
就可以達成我們所要的效果了。